2 * CDE - Common Desktop Environment
4 * Copyright (c) 1993-2012, The Open Group. All rights reserved.
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)
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
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
23 /* lcSjis.c 1.1 - Fujitsu source for CDEnext 95/11/06 20:32:40 */
24 /* $XConsortium: _fallcSjis.c /main/1 1996/04/08 15:18:51 cde-fuj $ */
25 /****************************************************************
27 Copyright 1992, 1993 by FUJITSU LIMITED
28 Copyright 1993 by Fujitsu Open Systems Solutions, Inc.
29 Copyright 1994 by Sony Corporation
31 Permission to use, copy, modify, distribute and sell this software
32 and its documentation for any purpose is hereby granted without fee,
33 provided that the above copyright notice appear in all copies and
34 that both that copyright notice and this permission notice appear
35 in supporting documentation, and that the name of FUJITSU LIMITED,
36 Fujitsu Open Systems Solutions, Inc. and Sony Corporation not be
37 used in advertising or publicity pertaining to distribution of the
38 software without specific, written prior permission.
39 FUJITSU LIMITED, Fujitsu Open Systems Solutions, Inc. and
40 Sony Corporation make no representations about the suitability of
41 this software for any purpose. It is provided "as is" without
42 express or implied warranty.
44 FUJITSU LIMITED, FUJITSU OPEN SYSTEMS SOLUTIONS, INC. AND SONY
45 CORPORATION DISCLAIM ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
46 INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS,
47 IN NO EVENT SHALL FUJITSU OPEN SYSTEMS SOLUTIONS, INC., FUJITSU LIMITED
48 AND SONY CORPORATION BE LIABLE FOR ANY SPECIAL, INDIRECT OR
49 CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS
50 OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
51 OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE
52 OR PERFORMANCE OF THIS SOFTWARE.
54 Authors: Jeffrey Bloomfield (jeffb@ossi.com)
55 Shigeru Yamada (yamada@ossi.com)
56 Yoshiyuki Segawa (segawa@ossi.com)
57 Modifier:Makoto Wakamatsu Sony Corporation
60 *****************************************************************/
62 #include "_fallibint.h"
63 #include "_fallcGeneric.h"
67 #define isascii __isascii
70 #define CS0 codesets[0] /* Codeset 0 - 7-bit ASCII */
71 #define CS1 codesets[1] /* Codeset 1 - Kanji */
72 #define CS2 codesets[2] /* Codeset 2 - Half-Kana */
73 #define CS3 codesets[3] /* Codeset 3 - User defined */
75 #define ascii (codeset->cs_num == 0)
76 #define kanji (codeset->cs_num == 1)
77 #define kana (codeset->cs_num == 2)
78 #define userdef (codeset->cs_num == 3)
80 #define ASCII_CODESET 0
81 #define KANJI_CODESET 1
82 #define KANA_CODESET 2
83 #define USERDEF_CODESET 3
84 #define MAX_CODESETS 4
86 #define GR 0x80 /* begins right-side (non-ascii) region */
87 #define GL 0x7f /* ends left-side (ascii) region */
89 #define isleftside(c) (((c) & GR) ? 0 : 1)
90 #define isrightside(c) (!isleftside(c))
92 typedef unsigned char Uchar;
93 typedef unsigned long Ulong;
94 typedef unsigned int Uint;
96 /* Acceptable range for 2nd byte of SJIS multibyte char */
97 #define VALID_MULTIBYTE(c) \
98 ((0x40<=((Uchar)c) && ((Uchar)c)<=0x7e) \
99 || (0x80<=((Uchar)c) && ((Uchar)c)<=0xfc))
102 #define iskanji(c) ((0x81<=((Uchar)c) && ((Uchar)c)<=0x9f) \
103 || (0xe0<=((Uchar)c) && ((Uchar)c)<=0xef))
104 #endif /* !iskanji */
107 #define iskana(c) (0xa1<=((Uchar)c) && ((Uchar)c)<=0xdf)
110 #define isuserdef(c) (0xf0<=((Uchar)c) && ((Uchar)c)<=0xfc)
112 #define BIT8OFF(c) ((c) & GL)
113 #define BIT8ON(c) ((c) | GR)
116 static void jis_to_sjis();
117 static void sjis_to_jis();
118 static CodeSet wc_codeset();
123 * 1. 16-bit widechar format is limited to 14 data bits. Since the 2nd byte
124 * of SJIS multibyte chars are in the ranges of 0x40 - 7E and 0x80 - 0xFC,
125 * SJIS cannot map directly into 16 bit widechar format within the confines
126 * of a single codeset. Therefore, for SJIS widechar conversion, SJIS Kanji
127 * is mapped into the JIS codeset. (The algorithms used in jis_to_sjis()
128 * and sjis_to_jis() are from Ken Lunde (lunde@mv.us.adobe.com) and are in
129 * the public domain.)
130 * 2. Defining FORCE_INDIRECT_CONVERTER (see _fallcEucLoader())
131 * forces indirect (charset) conversions (e.g. wcstocs()<->cstombs()).
132 * 3. Using direct converters (e.g. mbstowcs()) decreases conversion
133 * times by 20-40% (depends on specific converter used).
138 sjis_mbstowcs(conv, from, from_left, to, to_left, args, num_args)
148 XLCd lcd = (XLCd)conv->state;
150 register int chr_len = 0;
151 register int outbuf = 0;
152 register int shift_mult = 0;
153 register Uint chrcode = 0;
166 XPointer inbufptr = *from;
167 wchar_t *outbufptr = (wchar_t *) *to;
168 wchar_t *outbuf_base = outbufptr;
170 CodeSet *codesets = XLC_GENERIC(lcd, codeset_list);
171 int codeset_num = XLC_GENERIC(lcd, codeset_num);
172 Ulong wc_shift = XLC_GENERIC(lcd, wc_shift_bits);
175 if (*from_left > *to_left)
176 *from_left = *to_left;
178 for (new_char = True, firstbyte = True; *from_left > 0; (*from_left)--) {
183 if (ASCII_CODESET >= codeset_num) {
189 length = CS0->length;
190 *outbufptr++ = (wchar_t)ch;
193 else if (iskanji(ch)) {
194 if (KANJI_CODESET >= codeset_num) {
200 length = CS1->length;
201 if (*from_left < length || *to_left < length)
203 wc_encode = CS1->wc_encoding;
205 sjis_to_jis(&ch, &ch2);
208 else if (iskana(ch)) {
209 if (KANA_CODESET >= codeset_num) {
214 length = CS2->length;
215 wc_encode = CS2->wc_encoding;
216 chrcode = BIT8OFF(ch);
218 else if (isuserdef(ch)) {
219 if (USERDEF_CODESET >= codeset_num) {
225 length = CS3->length;
226 if (*from_left < length || *to_left < length)
228 wc_encode = CS3->wc_encoding;
230 sjis_to_jis(&ch, &ch2);
238 } else { /* 2nd byte of multibyte char */
239 if (!VALID_MULTIBYTE((Uchar) *(inbufptr-1))) {
248 shift_mult = length - 1;
252 chrcode <<= (wc_shift * shift_mult);
255 if (--chr_len == 0) {
257 *outbufptr++ = wc_tmp;
266 *to = (XPointer)outbufptr;
268 if ((num_conv = outbufptr - outbuf_base) > 0)
269 (*to_left) -= num_conv;
275 #define byte1 (length == codeset->length - 1)
276 #define byte2 (byte1 == 0)
279 sjis_wcstombs(conv, from, from_left, to, to_left, args, num_args)
288 register wchar_t *inbufptr = (wchar_t *) *from;
289 register XPointer outbufptr = *to;
290 XPointer outbuf_base = outbufptr;
298 XLCd lcd = (XLCd)conv->state;
300 Ulong wc_encoding_mask = XLC_GENERIC(lcd, wc_encode_mask);
301 Ulong wc_shift = XLC_GENERIC(lcd, wc_shift_bits);
305 if (*from_left > *to_left)
306 *from_left = *to_left;
308 for (; *from_left > 0 ; (*from_left)-- ) {
312 if (!(codeset = wc_codeset(lcd, wch))) {
318 length = codeset->length;
319 wch ^= (wchar_t)codeset->wc_encoding;
323 tmp = wch>>(wchar_t)( (Ulong)length * wc_shift);
328 else if (byte1 && (kanji || userdef)) {
333 else if (byte2 && (kanji || userdef)) {
335 jis_to_sjis(&t1, &t2);
336 *outbufptr++ = (char)t1;
340 *outbufptr++ = (char)tmp;
345 *to = (XPointer)outbufptr;
347 if ((num_conv = (int)(outbufptr - outbuf_base)) > 0)
348 (*to_left) -= num_conv;
356 * sjis<->jis conversion for widechar kanji (See Note at top of file)
363 register Uchar c1 = *p1;
364 register Uchar c2 = *p2;
365 register Uchar adjust = c2 < 0x9f;
366 register Uchar rowOffset = c1 < 0xa0 ? 0x70 : 0xb0;
367 register Uchar cellOffset = adjust ? (0x1f + (c2 > 0x7f)) : 0x7e;
369 *p1 = ((c1 - rowOffset) << 1) - adjust;
378 register Uchar c1 = *p1;
379 register Uchar c2 = *p2;
380 register Uchar rowOffset = c1 < 0x5f ? 0x70 : 0xb0;
381 register Uchar cellOffset = c1 % 2 ? 0x1f + (c2 > 0x5f) : 0x7e;
383 *p1 = ((Uchar)(c1 + 1) >> 1) + rowOffset;
384 *p2 = c2 + cellOffset;
392 register CodeSet *codesets = XLC_GENERIC(lcd, codeset_list);
393 #if !defined(__sony_news) || defined(SVR4)
394 register int end = XLC_GENERIC(lcd, codeset_num);
395 register Ulong widech = (Ulong)(wch & XLC_GENERIC(lcd, wc_encode_mask));
397 for (; --end >= 0; codesets++)
398 if ( widech == (*codesets)->wc_encoding )
403 if( iskanji(wch >> 8) )
404 return( codesets[1] );
405 if( iskana(wch & 0xff) )
406 return( codesets[2] );
407 return( codesets[0] );
413 sjis_mbtocs(conv, from, from_left, to, to_left, args, num_args)
422 XLCd lcd = (XLCd)conv->state;
423 XlcCharSet charset = NULL;
426 register char *src = *from, *dst = *to;
427 CodeSet *codesets = XLC_GENERIC(lcd, codeset_list);
428 int codeset_num = XLC_GENERIC(lcd, codeset_num);
432 if (KANJI_CODESET >= codeset_num)
434 charset = *CS1->charset_list;
435 char_size = charset->char_size;
437 if (*from_left >= char_size && *to_left >= char_size) {
440 if (!VALID_MULTIBYTE((Uchar) *(src-1))) /* check 2nd byte */
442 sjis_to_jis((Uchar *)(dst-2), (Uchar *)(dst-1));
446 else if (isuserdef(*src)) {
447 if (USERDEF_CODESET >= codeset_num)
449 charset = *CS3->charset_list;
450 char_size = charset->char_size;
452 if (*from_left >= char_size && *to_left >= char_size) {
455 if (!VALID_MULTIBYTE((Uchar) *(src-1))) /* check 2nd byte */
457 sjis_to_jis((Uchar *)(dst-2), (Uchar *)(dst-1));
461 else if (isascii(*src)) {
462 if (ASCII_CODESET >= codeset_num)
464 charset = *CS0->charset_list;
465 char_size = charset->char_size;
467 if (*from_left >= char_size && *to_left >= char_size)
472 else if (iskana(*src)) {
473 if (KANA_CODESET >= codeset_num)
475 charset = *CS2->charset_list;
476 char_size = charset->char_size;
478 if (*from_left >= char_size && *to_left >= char_size)
486 *from_left -= char_size;
487 *to_left -= char_size;
493 *((XlcCharSet *) args[0]) = charset;
500 sjis_mbstocs(conv, from, from_left, to, to_left, args, num_args)
509 XLCd lcd = (XLCd) conv->state;
510 char *tmp_from, *tmp_to;
511 int tmp_from_left, tmp_to_left;
512 XlcCharSet charset, tmp_charset;
513 XPointer tmp_args[1];
514 int unconv_num = 0, ret;
518 /* Determine the charset of the segment and convert one characater: */
520 tmp_args[0] = (XPointer) &charset; /* charset from sjis_mbtocs() */
522 ((ret = sjis_mbtocs(conv, from, from_left, to, to_left, tmp_args, 1)) > 0)
528 tmp_from_left = *from_left;
529 tmp_to_left = *to_left;
532 /* Convert remainder of the segment: */
534 tmp_args[0] = (XPointer) &tmp_charset;
535 while( (ret = sjis_mbtocs(conv, &tmp_from, &tmp_from_left, &tmp_to,
536 &tmp_to_left, tmp_args, 1)) >= 0 ) {
543 if (tmp_charset != charset) /* quit on end of segment */
547 *from_left = tmp_from_left;
549 *to_left = tmp_to_left;
553 *((XlcCharSet *) args[0]) = charset;
559 sjis_wcstocs(conv, from, from_left, to, to_left, args, num_args)
568 XLCd lcd = (XLCd) conv->state;
569 wchar_t *wcptr = *((wchar_t **)from);
570 register char *bufptr = *((char **) to);
576 int buf_len = *to_left;
578 int wcstr_len = *from_left;
581 if (!(codeset = wc_codeset(lcd, *wcptr)))
584 if (wcstr_len < buf_len / codeset->length)
585 buf_len = wcstr_len * codeset->length;
587 #if !defined(__sony_news) || defined(SVR4)
588 wc_encoding = codeset->wc_encoding;
590 for ( ; wcstr_len > 0 && buf_len > 0; wcptr++, wcstr_len--) {
593 if ((wch & XLC_GENERIC(lcd, wc_encode_mask)) != wc_encoding)
596 length = codeset->length;
603 *tmpptr-- = kana ? BIT8ON(wch) : BIT8OFF(wch);
604 wch >>= (wchar_t)XLC_GENERIC(lcd, wc_shift_bits);
608 length = codeset->length;
609 for( ; wcstr_len > 0 && buf_len > 0; wcptr++, wcstr_len-- ) {
611 if( codeset != wc_codeset( lcd, wch ) )
618 code = sjis2jis( wch & 0xffff );
619 *bufptr++ = code >> 8;
620 *bufptr++ = code & 0xff;
623 *bufptr++ = wch & 0xff;
628 *((XlcCharSet *) args[0]) = *codeset->charset_list;
630 *from_left -= wcptr - (wchar_t *) *from;
631 *from = (XPointer) wcptr;
633 *to_left -= bufptr - *to;
640 GetCodeSetFromCharSet(lcd, charset)
644 register CodeSet *codeset = XLC_GENERIC(lcd, codeset_list);
645 register XlcCharSet *charset_list;
646 register codeset_num, num_charsets;
648 codeset_num = XLC_GENERIC(lcd, codeset_num);
650 for ( ; codeset_num-- > 0; codeset++) {
651 num_charsets = (*codeset)->num_charsets;
652 charset_list = (*codeset)->charset_list;
654 for ( ; num_charsets-- > 0; charset_list++)
655 if (*charset_list == charset)
659 return (CodeSet) NULL;
664 sjis_cstombs(conv, from, from_left, to, to_left, args, num_args)
673 XLCd lcd = (XLCd) conv->state;
674 register char *csptr = *from;
675 register char *bufptr = *to;
676 int csstr_len = *from_left;
677 register buf_len = *to_left;
682 CodeSet *codesets = XLC_GENERIC(lcd, codeset_list);
688 if (!(codeset = GetCodeSetFromCharSet(lcd, (XlcCharSet) args[0])))
691 csstr_len /= codeset->length;
692 buf_len /= codeset->length;
693 if (csstr_len < buf_len)
696 cvt_length += buf_len * codeset->length;
700 length = codeset->length;
702 *bufptr++ = codeset->length == 1 && codeset->side == XlcGR ?
703 BIT8ON(*csptr++) : BIT8OFF(*csptr++);
705 if (codeset->length == 2)
706 jis_to_sjis((Uchar *)(bufptr-2), (Uchar *)(bufptr-1));
710 *from_left -= csptr - *from;
715 *to_left -= cvt_length;
722 sjis_cstowcs(conv, from, from_left, to, to_left, args, num_args)
731 XLCd lcd = (XLCd) conv->state;
732 register char *csptr = (char *) *from;
733 wchar_t *bufptr = (wchar_t *) *to;
734 wchar_t *toptr = (wchar_t *) *to;
735 int csstr_len = *from_left;
736 register buf_len = *to_left;
739 Ulong wc_shift_bits = (int)XLC_GENERIC(lcd, wc_shift_bits);
746 if (!(codeset = GetCodeSetFromCharSet(lcd, (XlcCharSet) args[0])))
749 csstr_len /= codeset->length;
750 if (csstr_len < buf_len)
758 *to = (XPointer) toptr;
761 wch = (wchar_t) BIT8OFF(*csptr);
764 length = codeset->length - 1;
766 wch = (wch << wc_shift_bits) | BIT8OFF(*csptr);
769 *bufptr++ = wch | codeset->wc_encoding;
773 *from_left -= csptr - *from;
781 * Stripped down Direct CT converters for SJIS
785 #define BADCHAR(min_ch, c) (BIT8OFF(c) < (char)min_ch && BIT8OFF(c) != 0x0 && \
786 BIT8OFF(c) != '\t' && BIT8OFF(c) != '\n' && \
789 typedef struct _CTDataRec {
799 } CTDataRec, *CTData;
801 typedef struct _StateRec {
807 static enum { CT_STD, CT_NSTD, CT_DIR, CT_EXT0, CT_EXT1, CT_EXT2, CT_VER }
810 static CTDataRec ctdata[] =
812 { XlcGL, 1, "ISO8859-1:GL", 0, "\033(B" , 3, 0, 0, CT_STD },
813 { XlcGR, 1, "ISO8859-1:GR", 0, "\033-A" , 3, 0, 0, CT_STD },
814 { XlcGL, 1, "JISX0201.1976-0:GL", 0, "\033(J" , 3, 0, 0, CT_STD },
815 { XlcGR, 1, "JISX0201.1976-0:GR", 0, "\033)I" , 3, 0, 0, CT_STD },
816 { XlcGL, 2, "JISX0208.1983-0:GL", 0, "\033$(B" , 4, 0, 0, CT_STD },
817 { XlcGR, 2, "JISX0208.1983-0:GR", 0, "\033$)B" , 4, 0, 0, CT_STD },
818 { XlcGL, 2, "JISX0212.1990-0:GL", 0, "\033$(D" , 4, 0, 0, CT_STD },
819 { XlcGR, 2, "JISX0212.1990-0:GR", 0, "\033$)D" , 4, 0, 0, CT_STD },
820 { XlcUnknown, 0, "Ignore-Ext-Status?", 0, "\033#" , 2, 0, 0, CT_VER },
821 { XlcUnknown, 0, "NonStd-?-OctetChar", 0, "\033%/0" , 4, 0, 0, CT_NSTD },
822 { XlcUnknown, 1, "NonStd-1-OctetChar", 0, "\033%/1" , 4, 0, 0, CT_NSTD },
823 { XlcUnknown, 2, "NonStd-2-OctetChar", 0, "\033%/2" , 4, 0, 0, CT_NSTD },
824 { XlcUnknown, 3, "NonStd-3-OctetChar", 0, "\033%/3" , 4, 0, 0, CT_NSTD },
825 { XlcUnknown, 4, "NonStd-4-OctetChar", 0, "\033%/4" , 4, 0, 0, CT_NSTD },
826 { XlcUnknown, 0, "Extension-2" , 0, "\033%/" , 3, 0, 0, CT_EXT2 },
827 { XlcUnknown, 0, "Extension-0" , 0, "\033" , 1, 0, 0, CT_EXT0 },
828 { XlcUnknown, 0, "Begin-L-to-R-Text", 0, "\2331]" , 3, 0, 0, CT_DIR },
829 { XlcUnknown, 0, "Begin-R-to-L-Text", 0, "\2332]" , 3, 0, 0, CT_DIR },
830 { XlcUnknown, 0, "End-Of-String", 0, "\233]" , 2, 0, 0, CT_DIR },
831 { XlcUnknown, 0, "Extension-1" , 0, "\233" , 1, 0, 0, CT_EXT1 },
834 /* Note on above table: sjis_ctstombs() and sjis_ctstowcs() parser depends on
835 * certain table entries occurring in decreasing string length--
836 * 1. CT_EXT2 and CT_EXT0 entries must occur after CT_NSTD entries.
837 * 2. CT_DIR and CT_EXT1 entries must occur after CT_DIR entries.
840 static CTData ctdptr[sizeof(ctdata) / sizeof(CTDataRec)];
841 static CTData ctd_endp = ctdata + ((sizeof(ctdata) / sizeof(CTDataRec))) - 1;
842 static enum { Ascii, Kanji, Kana, Userdef } cs_nums;
846 * initCTptr(): Set ctptr[] to point at ctdata[], indexed by codeset_num.
852 int num_codesets = XLC_GENERIC(lcd, codeset_num);
855 CodeSet *codesets = XLC_GENERIC(lcd, codeset_list);
858 CTData ctdp = ctdata;
860 ctdptr[Ascii] = &ctdata[0]; /* failsafe */
862 for (i = 0; i < num_codesets; i++) {
864 codeset = codesets[i];
865 num_charsets = codeset->num_charsets;
867 for (j = 0; j < num_charsets; j++) {
869 charset = codeset->charset_list[j];
871 for (ctdp = ctdata; ctdp <= ctd_endp; ctdp++)
873 if (! strcmp(ctdp->name, charset->name)) {
875 ctdptr[codeset->cs_num] = ctdp;
877 ctdptr[codeset->cs_num]->wc_encoding = codeset->wc_encoding;
879 ctdptr[codeset->cs_num]->set_size =
882 ctdptr[codeset->cs_num]->min_ch =
883 charset->set_size == 94 &&
884 (ctdptr[codeset->cs_num]->length > 1 ||
885 ctdptr[codeset->cs_num]->side == XlcGR) ? 0x21 : 0x20;
895 sjis_mbstocts(conv, from, from_left, to, to_left, args, num_args)
904 register ct_len = *to_left;
909 XPointer inbufptr = *from;
910 register char *ctptr = *to;
911 XPointer ct_base = ctptr;
915 XLCd lcd = (XLCd) conv->state;
916 int codeset_num = XLC_GENERIC(lcd, codeset_num);
921 ct_state.GL_charset = ctdptr[Ascii];
922 ct_state.GR_charset = NULL;
925 if (*from_left > *to_left)
926 *from_left = *to_left;
928 for (;*from_left > 0; (*from_left) -= charset->length) {
930 if (iskanji(*inbufptr)) {
931 if (KANJI_CODESET >= codeset_num) {
937 charset = ctdptr[Kanji];
938 if (!VALID_MULTIBYTE((Uchar) *(inbufptr+1)))
941 else if (isuserdef(*inbufptr)) {
942 if (USERDEF_CODESET >= codeset_num) {
948 charset = ctdptr[Userdef];
949 if (!VALID_MULTIBYTE((Uchar) *(inbufptr+1)))
952 else if (isascii(*inbufptr)) {
953 if (ASCII_CODESET >= codeset_num) {
959 charset = ctdptr[Ascii];
961 else if (iskana(*inbufptr)) {
962 if (KANA_CODESET >= codeset_num) {
968 charset = ctdptr[Kana];
976 if ( (charset->side == XlcGR && charset != ct_state.GR_charset) ||
977 (charset->side == XlcGL && charset != ct_state.GL_charset) ) {
979 ct_len -= ctdptr[cs_num]->ct_encoding_len;
986 strcpy(ctptr, ctdptr[cs_num]->ct_encoding);
987 ctptr += ctdptr[cs_num]->ct_encoding_len;
991 clen = charset->length;
993 *ctptr++ = *inbufptr++;
996 if (charset->length >= 2) {
997 sjis_to_jis((Uchar *)(ctptr-2), (Uchar *)(ctptr-1));
998 if (BADCHAR(charset->min_ch, *(ctptr-2)) ||
999 BADCHAR(charset->min_ch, *(ctptr-1))) {
1005 if (BADCHAR(charset->min_ch, *(ctptr-1))) {
1010 if (charset->side == XlcGR)
1011 ct_state.GR_charset = charset;
1012 else if (charset->side == XlcGL)
1013 ct_state.GL_charset = charset;
1016 *to = (XPointer)ctptr;
1018 if ((num_conv = (int)(ctptr - ct_base)) > 0)
1019 (*to_left) -= num_conv;
1026 #define byte1 (length == codeset->length - 1)
1027 #define byte2 (byte1 == 0)
1030 sjis_wcstocts(conv, from, from_left, to, to_left, args, num_args)
1039 register ct_len = *to_left;
1040 register wchar_t *inbufptr = (wchar_t *) *from;
1041 register char *ctptr = *to;
1042 XPointer ct_base = ctptr;
1050 XLCd lcd = (XLCd)conv->state;
1054 Ulong wc_encoding_mask = XLC_GENERIC(lcd, wc_encode_mask);
1055 Ulong wc_shift = XLC_GENERIC(lcd, wc_shift_bits);
1058 /* Initial State: */
1059 ct_state.GL_charset = ctdptr[0]; /* Codeset 0 */
1060 ct_state.GR_charset = NULL;
1062 if (*from_left > *to_left)
1063 *from_left = *to_left;
1065 for (; *from_left > 0 ; (*from_left)-- ) {
1069 if (!(codeset = wc_codeset(lcd, wch))) {
1075 charset = ctdptr[codeset->cs_num];
1077 length = codeset->length;
1078 wch ^= (wchar_t)codeset->wc_encoding;
1080 if ( (charset->side == XlcGR && charset != ct_state.GR_charset) ||
1081 (charset->side == XlcGL && charset != ct_state.GL_charset) ) {
1083 ct_len -= ctdptr[codeset->cs_num]->ct_encoding_len;
1090 strcpy(ctptr, ctdptr[codeset->cs_num]->ct_encoding);
1091 ctptr += ctdptr[codeset->cs_num]->ct_encoding_len;
1096 if (charset->side == XlcGR)
1097 ct_state.GR_charset = charset;
1098 else if (charset->side == XlcGL)
1099 ct_state.GL_charset = charset;
1103 tmp = wch>>(wchar_t)( (Ulong)length * wc_shift);
1106 if (BADCHAR(charset->min_ch, (char)tmp)) {
1110 *ctptr++ = (char)BIT8ON(tmp);
1113 else if (byte1 && (kanji || userdef)) {
1117 else if (byte2 && (kanji || userdef)) {
1118 if (BADCHAR(charset->min_ch, (char)t1) ||
1119 BADCHAR(charset->min_ch, (char)tmp)) {
1124 *ctptr++ = (char)BIT8OFF(t1);
1125 *ctptr++ = (char)BIT8OFF(tmp);
1129 if (BADCHAR(charset->min_ch, (char)tmp)) {
1133 *ctptr++ = (char)tmp;
1139 *to = (XPointer)ctptr;
1141 if ((num_conv = (int)(ctptr - ct_base)) > 0)
1142 (*to_left) -= num_conv;
1149 #define SKIP_I(str) while (*(str) >= 0x20 && *(str) <= 0x2f) (str)++;
1150 #define SKIP_P(str) while (*(str) >= 0x30 && *(str) <= 0x3f) (str)++;
1153 sjis_ctstombs(conv, from, from_left, to, to_left, args, num_args)
1162 register XPointer inbufptr = *from;
1163 register XPointer outbufptr = *to;
1164 XPointer inbuf_base;
1165 XPointer outbuf_base = outbufptr;
1166 register clen, length;
1169 unsigned int ct_seglen = 0;
1171 CTData ctdp = ctdata; /* default */
1174 if (*from_left > *to_left)
1175 *from_left = *to_left;
1177 for (length = ctdata[Ascii].length; *from_left > 0 ; (*from_left) -= length)
1180 if (*inbufptr == '\033' || *inbufptr == (char)'\233') {
1182 for (ctdp = ctdata; ctdp <= ctd_endp ; ctdp++) {
1184 if(!strncmp(inbufptr, ctdp->ct_encoding, ctdp->ct_encoding_len))
1186 inbufptr += ctdp->ct_encoding_len;
1187 (*from_left) -= ctdp->ct_encoding_len;
1188 if( ctdp->length ) {
1189 length = ctdp->length;
1190 if( *from_left < length ) {
1191 *to = (XPointer)outbufptr;
1192 *to_left -= outbufptr - outbuf_base;
1193 return( unconv_num + *from_left );
1196 ct_type = ctdp->ct_type;
1200 if (ctdp > ctd_endp) /* failed to match CT sequence */
1204 /* The following code insures that non-standard encodings, direction, extension,
1205 * and version strings are ignored; subject to change in future.
1214 ct_seglen = (BIT8OFF(*inbufptr) << 7) + BIT8OFF(*(inbufptr+1)) + 2;
1215 inbufptr += ct_seglen;
1216 (*from_left) -= ct_seglen;
1219 inbuf_base = inbufptr;
1222 ct_seglen = (unsigned)(inbufptr - inbuf_base);
1223 (*from_left) -= ct_seglen;
1226 inbuf_base = inbufptr;
1230 ct_seglen = (unsigned)(inbufptr - inbuf_base);
1231 (*from_left) -= ct_seglen;
1243 *outbufptr++ = *inbufptr++;
1247 jis_to_sjis((Uchar *)(outbufptr-2), (Uchar *)(outbufptr-1));
1250 *to = (XPointer)outbufptr;
1252 if ((num_conv = (int)(outbufptr - outbuf_base)) > 0)
1253 (*to_left) -= num_conv;
1260 sjis_ctstowcs(conv, from, from_left, to, to_left, args, num_args)
1269 XLCd lcd = (XLCd)conv->state;
1270 Ulong wc_shift_bits = XLC_GENERIC(lcd, wc_shift_bits);
1271 register XPointer inbufptr = *from;
1272 XPointer inbuf_base;
1273 register wchar_t *outbufptr = (wchar_t *) *to;
1274 wchar_t *outbuf_base = outbufptr;
1275 register clen, length;
1278 unsigned int ct_seglen = 0;
1280 register shift_mult;
1284 CTData ctdp = ctdata;
1287 if (*from_left > *to_left)
1288 *from_left = *to_left;
1290 for (length = ctdata[Ascii].length; *from_left > 0; (*from_left) -= length )
1293 if (*inbufptr == '\033' || *inbufptr == (char)'\233') {
1294 for (ctdp = ctdata; ctdp <= ctd_endp ; ctdp++) {
1296 if(!strncmp(inbufptr, ctdp->ct_encoding, ctdp->ct_encoding_len))
1298 inbufptr += ctdp->ct_encoding_len;
1299 (*from_left) -= ctdp->ct_encoding_len;
1300 if( ctdp->length ) {
1301 length = ctdp->length;
1302 if( *from_left < length ) {
1303 *to = (XPointer)outbufptr;
1304 *to_left -= outbufptr - outbuf_base;
1305 return( unconv_num + *from_left );
1308 ct_type = ctdp->ct_type;
1312 if (ctdp > ctd_endp) /* failed to match CT sequence */
1316 /* The following block of code insures that non-standard encodings, direction,
1317 * extension, and version strings are ignored; subject to change in future.
1326 ct_seglen = (BIT8OFF(*inbufptr) << 7) + BIT8OFF(*(inbufptr+1)) + 2;
1327 inbufptr += ct_seglen;
1328 (*from_left) -= ct_seglen;
1331 inbuf_base = inbufptr;
1334 ct_seglen = (unsigned)(inbufptr - inbuf_base);
1335 (*from_left) -= ct_seglen;
1338 inbuf_base = inbufptr;
1342 ct_seglen = (unsigned)(inbufptr - inbuf_base);
1343 (*from_left) -= ct_seglen;
1352 #if !defined(__sony_news) || defined(SVR4)
1353 wc_encoding = (ctdp == ctdptr[Kana] && isleftside(*inbufptr)) ?
1354 ctdptr[Ascii]->wc_encoding : ctdp->wc_encoding;
1356 shift_mult = length - 1;
1361 wc_tmp = BIT8OFF(*inbufptr++) << (wc_shift_bits * shift_mult);
1365 *outbufptr++ = wch | wc_encoding;
1368 *outbufptr++ = (unsigned char)*inbufptr++;
1369 else if( length == 2 ) {
1370 unsigned short code;
1371 code = (*inbufptr << 8) | *(inbufptr+1);
1372 *outbufptr++ = jis2sjis( code );
1377 *to = (XPointer)outbufptr;
1379 if ((num_conv = (int)(outbufptr - outbuf_base)) > 0)
1380 (*to_left) -= num_conv ;
1388 close_converter(conv)
1391 Xfree((char *) conv);
1396 create_conv(lcd, methods)
1398 XlcConvMethods methods;
1402 conv = (XlcConv) Xmalloc(sizeof(XlcConvRec));
1404 return (XlcConv) NULL;
1406 conv->methods = methods;
1407 conv->state = (XPointer) lcd;
1412 enum { MBSTOCS, WCSTOCS, MBTOCS, CSTOMBS, CSTOWCS, MBSTOWCS, WCSTOMBS,
1413 WCSTOCTS, MBSTOCTS, CTSTOMBS, CTSTOWCS };
1415 static XlcConvMethodsRec conv_methods[] = {
1416 {close_converter, sjis_mbstocs, NULL },
1417 {close_converter, sjis_wcstocs, NULL },
1418 {close_converter, sjis_mbtocs, NULL },
1419 {close_converter, sjis_cstombs, NULL },
1420 {close_converter, sjis_cstowcs, NULL },
1421 {close_converter, sjis_mbstowcs, NULL },
1422 {close_converter, sjis_wcstombs, NULL },
1423 {close_converter, sjis_wcstocts, NULL },
1424 {close_converter, sjis_mbstocts, NULL },
1425 {close_converter, sjis_ctstombs, NULL },
1426 {close_converter, sjis_ctstowcs, NULL },
1431 open_mbstocs(from_lcd, from_type, to_lcd, to_type)
1437 return create_conv(from_lcd, &conv_methods[MBSTOCS]);
1441 open_wcstocs(from_lcd, from_type, to_lcd, to_type)
1447 return create_conv(from_lcd, &conv_methods[WCSTOCS]);
1451 open_mbtocs(from_lcd, from_type, to_lcd, to_type)
1457 return create_conv(from_lcd, &conv_methods[MBTOCS]);
1461 open_cstombs(from_lcd, from_type, to_lcd, to_type)
1467 return create_conv(from_lcd, &conv_methods[CSTOMBS]);
1471 open_cstowcs(from_lcd, from_type, to_lcd, to_type)
1477 return create_conv(from_lcd, &conv_methods[CSTOWCS]);
1481 open_mbstowcs(from_lcd, from_type, to_lcd, to_type)
1487 return create_conv(from_lcd, &conv_methods[MBSTOWCS]);
1491 open_wcstombs(from_lcd, from_type, to_lcd, to_type)
1497 return create_conv(from_lcd, &conv_methods[WCSTOMBS]);
1501 open_wcstocts(from_lcd, from_type, to_lcd, to_type)
1507 return create_conv(from_lcd, &conv_methods[WCSTOCTS]);
1511 open_mbstocts(from_lcd, from_type, to_lcd, to_type)
1517 return create_conv(from_lcd, &conv_methods[MBSTOCTS]);
1521 open_ctstombs(from_lcd, from_type, to_lcd, to_type)
1527 return create_conv(from_lcd, &conv_methods[CTSTOMBS]);
1531 open_ctstowcs(from_lcd, from_type, to_lcd, to_type)
1537 return create_conv(from_lcd, &conv_methods[CTSTOWCS]);
1541 _fallcSjisLoader(name)
1545 CodeSet *codeset_list;
1547 lcd = _fallcCreateLC(name, _fallcGenericMethods);
1551 if ((_fallcCompareISOLatin1(XLC_PUBLIC_PART(lcd)->codeset, "sjis"))) {
1552 _fallcDestroyLC(lcd);
1558 _fallcSetConverter(lcd, XlcNMultiByte, lcd, XlcNCharSet, open_mbstocs);
1559 _fallcSetConverter(lcd, XlcNWideChar, lcd, XlcNCharSet, open_wcstocs);
1560 _fallcSetConverter(lcd, XlcNCharSet, lcd, XlcNMultiByte, open_cstombs);
1561 _fallcSetConverter(lcd, XlcNCharSet, lcd, XlcNWideChar, open_cstowcs);
1562 _fallcSetConverter(lcd, XlcNMultiByte, lcd, XlcNChar, open_mbtocs);
1564 #ifndef FORCE_INDIRECT_CONVERTER
1565 _fallcSetConverter(lcd, XlcNCompoundText, lcd, XlcNMultiByte, open_ctstombs);
1566 _fallcSetConverter(lcd, XlcNCompoundText, lcd, XlcNWideChar, open_ctstowcs);
1567 _fallcSetConverter(lcd, XlcNMultiByte, lcd, XlcNCompoundText, open_mbstocts);
1568 _fallcSetConverter(lcd, XlcNMultiByte, lcd, XlcNWideChar, open_mbstowcs);
1569 _fallcSetConverter(lcd, XlcNWideChar, lcd, XlcNCompoundText, open_wcstocts);
1570 _fallcSetConverter(lcd, XlcNWideChar, lcd, XlcNMultiByte, open_wcstombs);